package database

import (
	"context"
	"fmt"
	"log"
	"time"

	"github.com/jackc/pgx/v5/pgxpool"
	"me.com/onePass/internal/config"
)

// PostgresClient PostgreSQL客户端
type PostgresClient struct {
	Pool *pgxpool.Pool
}

// NewPostgresClient 创建PostgreSQL连接池
func NewPostgresClient(cfg *config.Config) (*PostgresClient, error) {
	dsn := cfg.GetPostgresDSN()

	poolConfig, err := pgxpool.ParseConfig(dsn)
	if err != nil {
		return nil, fmt.Errorf("failed to parse connection string: %w", err)
	}

	// 配置连接池
	poolConfig.MaxConns = int32(cfg.Database.Postgres.MaxConnections)
	poolConfig.MinConns = int32(cfg.Database.Postgres.MaxIdleConnections)

	// 设置连接超时
	if timeout, err := time.ParseDuration(cfg.Database.Postgres.ConnectionTimeout); err == nil {
		poolConfig.ConnConfig.ConnectTimeout = timeout
	}

	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	pool, err := pgxpool.NewWithConfig(ctx, poolConfig)
	if err != nil {
		return nil, fmt.Errorf("failed to create connection pool: %w", err)
	}

	// 测试连接
	if err := pool.Ping(ctx); err != nil {
		return nil, fmt.Errorf("failed to ping database: %w", err)
	}

	log.Printf("PostgreSQL连接成功: %s:%d/%s", 
		cfg.Database.Postgres.Host, 
		cfg.Database.Postgres.Port, 
		cfg.Database.Postgres.Database)

	return &PostgresClient{Pool: pool}, nil
}

// Close 关闭数据库连接
func (c *PostgresClient) Close() {
	if c.Pool != nil {
		c.Pool.Close()
		log.Println("PostgreSQL连接已关闭")
	}
}

// HealthCheck 数据库健康检查
func (c *PostgresClient) HealthCheck() error {
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	return c.Pool.Ping(ctx)
}

// TestConnection 测试数据库连接并返回基本信息
func (c *PostgresClient) TestConnection() (string, error) {
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	var (
		version     string
		currentTime time.Time
		database    string
	)

	// 获取数据库版本
	err := c.Pool.QueryRow(ctx, "SELECT version(), NOW(), current_database()").Scan(&version, &currentTime, &database)
	if err != nil {
		return "", fmt.Errorf("failed to query database info: %w", err)
	}

	info := fmt.Sprintf("数据库连接测试成功:\n- 数据库: %s\n- 版本: %s\n- 服务器时间: %s",
		database, version, currentTime.Format("2006-01-02 15:04:05"))

	return info, nil
}